#ifndef SERIALIZE_HPP
#define SERIALIZE_HPP

#include <algorithm>
#include <cstdint>
#include <iterator>
#include <sstream>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>

namespace Serialization {

// 用于判断是否可以平凡复制
template <typename T>
constexpr bool IsTriviallyCopyable = std::is_trivially_copyable<T>::value;

// 序列化
template <typename T>
void serialize(std::ostream &os, const T &val, typename std::enable_if<IsTriviallyCopyable<T>, int>::type = 0) {
  os.write(reinterpret_cast<const char *>(&val), sizeof(T));
}

// 处理 std::pair
template <typename K, typename V>
void serialize(std::ostream &os, const std::pair<K, V> &val) {
  serialize(os, val.first);
  serialize(os, val.second);
}

// 处理 std::string
void serialize(std::ostream &os, const std::string &val) {
  const std::size_t size = val.size();
  os.write(reinterpret_cast<const char *>(&size), sizeof(size));
  os.write(val.data(), size);  // 注意这里的数据类型匹配
}

// 序列化容器
template <typename Container>
void serialize(
    std::ostream &os, const Container &container,
    typename std::enable_if<std::is_same<typename std::iterator_traits<typename Container::iterator>::value_type,
                                         typename Container::value_type>::value,
                            int>::type = 0) {
  const std::size_t size = container.size();
  os.write(reinterpret_cast<const char *>(&size), sizeof(size));
  for (const auto &item : container) {
    serialize(os, item);
  }
}

// 序列化元组
template <typename Tuple, std::size_t... Indices>
void serializeTuple(std::ostream &os, const Tuple &tup, std::index_sequence<Indices...>) {
  // 使用循环替代折叠表达式
  int dummy[] = {(serialize(os, std::get<Indices>(tup)), 0)...};  // 创建一个无用数组来展开索引
  static_cast<void>(dummy);                                       // 消除未使用变量的警告
}

template <typename... Args>
void serialize(std::ostream &os, const std::tuple<Args...> &val) {
  serializeTuple(os, val, std::index_sequence_for<Args...>{});
}

// 反序列化
template <typename T>
void deserialize(std::istream &is, T &val, typename std::enable_if<IsTriviallyCopyable<T>, int>::type = 0) {
  is.read(reinterpret_cast<char *>(&val), sizeof(T));
}

// 处理 std::string
void deserialize(std::istream &is, std::string &val) {
  std::size_t size = 0;
  is.read(reinterpret_cast<char *>(&size), sizeof(size));
  val.resize(size);
  is.read(&val[0], size);  // 使用 &val[0] 以获得 char* 类型
}

// 反序列化容器
template <typename Container>
void deserialize(
    std::istream &is, Container &container,
    typename std::enable_if<std::is_same<typename std::iterator_traits<typename Container::iterator>::value_type,
                                         typename Container::value_type>::value,
                            int>::type = 0) {
  std::size_t size = 0;
  is.read(reinterpret_cast<char *>(&size), sizeof(size));
  container.clear();
  container.reserve(size);
  for (std::size_t i = 0; i < size; ++i) {
    typename Container::value_type item;
    deserialize(is, item);
    container.emplace_back(std::move(item));
  }
}

// 反序列化元组
template <typename Tuple, std::size_t... Indices>
void DeserializeTuple(std::istream &is, Tuple &tup, std::index_sequence<Indices...>) {
  // 使用循环替代折叠表达式
  int dummy[] = {(deserialize(is, std::get<Indices>(tup)), 0)...};  // 创建一个无用数组来展开索引
  static_cast<void>(dummy);                                         // 消除未使用变量的警告
}

template <typename... Args>
void deserialize(std::istream &is, std::tuple<Args...> &val) {
  DeserializeTuple(is, val, std::index_sequence_for<Args...>{});
}

}  // namespace Serialization

#endif  // SERIALIZE_HPP
